package com.magic8ball;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

public class Magic8Ball extends Activity implements SensorListener
{
	private TextView window;
	private SensorManager sensors;
	private SharedPreferences preferences;
    private PowerManager.WakeLock wakeLock;
    private boolean wakeLockEngaged = false;
    
	//initialize preference variables
	boolean autoShake;
    boolean legacyMode;
    boolean screenDim;
    int response_color;
    int response_set;
    Map<Integer, String> custom_responses = new HashMap<Integer, String>();
    int xShakeThreshold;
    int yShakeThreshold;
    int shakeNumber;
    int shakeTime;
    
    //initialize shake variables
    int sensorCount = 0;
    int shakeNegX = 0;
    int shakePosX = 0;
    int shakePosY = 0;
    int shakeNegY = 0;
    int shakeZ = 0;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    
        //get preferences
        getPreferences();
        
        //set up wake lock
       	PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
       	wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "Magic 8-Ball");
        
        //listen to sensor
        sensors = (SensorManager) getSystemService(SENSOR_SERVICE);
        setContentView(R.layout.main);

        //shake if auto_shake is on
        if (autoShake)
        	updateAnswer(0);
    }
    
    @Override
    public void onResume()
    {
        super.onResume();
        
        //make sure the message window is blank
        window = (TextView) findViewById(R.id.message);
        window.setText("");
    
        //get preferences
        getPreferences();
        
        //shake if auto_shake is on
        if (autoShake)
        	updateAnswer(0);
        
        //listen to sensor
		sensors.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME);
		
        //lock the screen
		if (screenDim)
		{
			wakeLock.acquire();
			wakeLockEngaged = true;
		}
    }
    
    @Override
    protected void onPause()
    {
    	super.onPause();

        //stop locking the screen
    	if (wakeLockEngaged)
    	{
    		wakeLock.release();
    		wakeLockEngaged = false;
    	}
    }
    
    public void getPreferences()
    {
    	//load preference variables with chosen values
    	preferences = PreferenceManager.getDefaultSharedPreferences(this);
    	
    	//set preference variables
        autoShake = preferences.getBoolean("autoShake", false);
        legacyMode = preferences.getBoolean("legacyMode", false);
        screenDim = preferences.getBoolean("screenDim", true);
        response_color = Color.parseColor(preferences.getString("response_color", "#0000ff"));
        response_set = Integer.parseInt(preferences.getString("response_set", "99"));
        if (response_set == 99)
        {
        	String language = getBaseContext().getResources().getConfiguration().locale.getLanguage();
        	if (language.equals("fr"))
        		response_set = 1;
        	else if (language.equals("de"))
        		response_set = 2;
        	else if (language.equals("it"))
        		response_set = 3;
        	else if (language.equals("pl"))
        		response_set = 6;
        	else if (language.equals("es"))
        		response_set = 4;
        	else if (language.equals("nl"))
        		response_set = 7;
        	else if (language.equals("ru"))
        		response_set = 8;
        	else if (language.equals("cs"))
        		response_set = 9;
        	else if (language.equals("da"))
        		response_set = 10;
        	else if (language.equals("he"))
        		response_set = 11;
        	else if (language.equals("zh"))
        		response_set = 12;
        	else if (language.equals("hu"))
        		response_set = 13;
        	else
        		response_set = 0;
        }
        String all_custom_responses = "";
        int i = 0;
        while(i <= 19)
        {
        	all_custom_responses += preferences.getString("custom"+(i+1), "");
        	custom_responses.put(i, preferences.getString("custom"+(i+1), ""));
        	i++;
        }
        if (all_custom_responses.equals(""))
        	custom_responses. put(0, getResources().getString(R.string.no_responses_message));
        xShakeThreshold = Integer.parseInt(preferences.getString("xShakeThreshold", "5"));
        yShakeThreshold = Integer.parseInt(preferences.getString("yShakeThreshold", "2"));
        shakeNumber = Integer.parseInt(preferences.getString("shakeNumber", "2"));
        shakeTime = Integer.parseInt(preferences.getString("shakeTime", "5"));
    }
    
    public void onSensorChanged(int sensor, float[] values)
    {
    	//count the sensor changes
    	sensorCount += 1;
    	
    	//keep track of the number of shakes
    	if (values[0] < -xShakeThreshold)
    		shakeNegX += 1;
    	if (values[0] > xShakeThreshold)
    		shakePosX += 1;
    	if (values[1] > yShakeThreshold)
    		shakePosY += 1;	
    	if (values[1] < -yShakeThreshold)
    		shakeNegY += 1;	
    	if (values[2] > 6)
    		shakeZ += 1;
    	
    	//update the 8ball if shaken enough
    	if (legacyMode)
    	{
    		if ((shakeZ >= 4) && values[2] > 6)
       		{
       			updateAnswer(2);
       			resetShake();
        	}
    	}
    	else
    	{
   			if ((shakePosX >= shakeNumber) && (shakeNegX >= shakeNumber))
        	{
        		updateAnswer(0);
       			resetShake();
       		}
        	else if ((shakePosY >= shakeNumber) && (shakeNegY >= shakeNumber))
        	{
       			updateAnswer(1);
       			resetShake();
       		}
   		}
    	
    	//too many sensor changes means too much time has passed
    	if (sensorCount > shakeTime)
    		resetShake();
    }

    private void resetShake()
    {
    	//clear the shake variables to reset the 8ball
        sensorCount = 0;
        shakeNegX = 0;
        shakePosX = 0;
        shakePosY = 0;
        shakeNegY = 0;
        shakeZ = 0;
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);
        
        //inflate the menu from xml
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu, menu);
       
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId()) {
        case R.id.shake:
        	updateAnswer(0);
        	return true;
        case R.id.settings:
        	startActivity(new Intent(this, Preferences.class));          
        	return true;
        }
        return false;
    }

    private void updateAnswer(int shake_axis)
    {
    	//randomly select the message text
    	String message = getAnswer();

        //load the message text to the view
        window = (TextView) findViewById(R.id.message);
        window.setText(message);
        window.setTextColor(response_color);
        
        //shake the background
        if (shake_axis == 0)
            findViewById(R.id.background).startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake_x));
        else if (shake_axis == 1)
            findViewById(R.id.background).startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake_y));
        
        //fade in the view
        AlphaAnimation fade = new AlphaAnimation(0, 1);
        fade.setStartOffset(1000);
        fade.setDuration(1000); 
        window.startAnimation(fade);
    }
    
    private String getAnswer()
    {
    	// get a random integer between 0 and 19 to randomly select an answer
    	Random randomGenerator = new Random();
        int randomInt = randomGenerator.nextInt(20);
        
        // select an answer based on the selected set
        String message = "";
        switch(response_set)
        {
    		case 0:
    			message = getResources().getStringArray(R.array.english)[randomInt];
    			break;
        	case 1:
        		message = getResources().getStringArray(R.array.french)[randomInt];
        		break;
        	case 2:
        		message = getResources().getStringArray(R.array.german)[randomInt];
        		break;
        	case 3:
        		message = getResources().getStringArray(R.array.italian)[randomInt];
        		break;
        	case 4:
        		message = getResources().getStringArray(R.array.spanish)[randomInt];
        		break;
        	case 5:
        		while (message.equals(""))
       			{
       				message = custom_responses.get(randomInt);
        			randomInt = randomGenerator.nextInt(20);
        		}
        		break;
        	case 6:
        		message = getResources().getStringArray(R.array.polish)[randomInt];
        		break;
        	case 7:
        		message = getResources().getStringArray(R.array.dutch)[randomInt];
        		break;
        	case 8:
        		message = getResources().getStringArray(R.array.russian)[randomInt];
        		break;
        	case 9:
        		message = getResources().getStringArray(R.array.czech)[randomInt];
        		break;
        	case 10:
        		message = getResources().getStringArray(R.array.danish)[randomInt];
        		break;
        	case 11:
        		message = getResources().getStringArray(R.array.hebrew)[randomInt];
        		break;
        	case 12:
        		message = getResources().getStringArray(R.array.chinese)[randomInt];
        		break;
        	case 13:
        		message = getResources().getStringArray(R.array.hungarian)[randomInt];
        		break;
        	default: break;
        }

        return message;
    }

	public void onAccuracyChanged(int sensor, int accuracy) {}
}